home *** CD-ROM | disk | FTP | other *** search
/ Openstep 4.2 (Developer) / Openstep Developer 4.2.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / unix.subproj / signal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  5.3 KB  |  209 lines

  1. /* signal.c
  2.    Signal handling routines.
  3.  
  4.    Copyright (C) 1992 Ian Lance Taylor
  5.  
  6.    This file is part of the Taylor UUCP package.
  7.  
  8.    This program is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU General Public License as
  10.    published by the Free Software Foundation; either version 2 of the
  11.    License, or (at your option) any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful, but
  14.    WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
  24.    */
  25.  
  26. #include "uucp.h"
  27.  
  28. #include "uudefs.h"
  29. #include "sysdep.h"
  30. #include "system.h"
  31.  
  32. #include <errno.h>
  33.  
  34. /* Signal handling routines.  When we catch a signal, we want to set
  35.    the appropriate elements of afSignal and afLog_signal to TRUE.  If
  36.    we are on a system which restarts system calls, we may also want to
  37.    longjmp out.  On a system which does not restart system calls,
  38.    these signal handling routines are well-defined by ANSI C.  */
  39.  
  40. #if HAVE_RESTARTABLE_SYSCALLS
  41. volatile sig_atomic_t fSjmp;
  42. volatile jmp_buf sSjmp_buf;
  43. #endif /* HAVE_RESTARTABLE_SYSCALLS */
  44.  
  45. /* Some systems, such as SunOS, have a SA_INTERRUPT bit that must be
  46.    set in the sigaction structure to force system calls to be
  47.    interrupted.  */
  48. #ifndef SA_INTERRUPT
  49. #define SA_INTERRUPT 0
  50. #endif
  51.  
  52. /* The SVR3 sigset function can be called just like signal, unless
  53.    system calls are restarted which is extremely unlikely; we prevent
  54.    this case in sysh.unx.  */
  55. #if HAVE_SIGSET && ! HAVE_SIGACTION && ! HAVE_SIGVEC
  56. #define signal sigset
  57. #endif
  58.  
  59. /* The sigvec structure changed from 4.2BSD to 4.3BSD.  These macros
  60.    make the 4.3 code backward compatible.  */
  61. #ifndef SV_INTERRUPT
  62. #define SV_INTERRUPT 0
  63. #endif
  64. #if ! HAVE_SIGVEC_SV_FLAGS
  65. #define sv_flags sv_onstack
  66. #endif
  67.  
  68. /* Catch a signal.  Reinstall the signal handler if necessary, set the
  69.    appropriate variables, and do a longjmp if necessary.  */
  70.  
  71. RETSIGTYPE
  72. ussignal (isig)
  73.      int isig;
  74. {
  75.   int iindex;
  76.  
  77. #if ! HAVE_SIGACTION && ! HAVE_SIGVEC && ! HAVE_SIGSET
  78.   (void) signal (isig, ussignal);
  79. #endif
  80.  
  81.   switch (isig)
  82.     {
  83.     default: iindex = INDEXSIG_SIGHUP; break;
  84. #ifdef SIGINT
  85.     case SIGINT: iindex = INDEXSIG_SIGINT; break;
  86. #endif
  87. #ifdef SIGQUIT
  88.     case SIGQUIT: iindex = INDEXSIG_SIGQUIT; break;
  89. #endif
  90. #ifdef SIGTERM
  91.     case SIGTERM: iindex = INDEXSIG_SIGTERM; break;
  92. #endif
  93. #ifdef SIGPIPE
  94.     case SIGPIPE: iindex = INDEXSIG_SIGPIPE; break;
  95. #endif
  96.     }
  97.  
  98.   afSignal[iindex] = TRUE;
  99.   afLog_signal[iindex] = TRUE;
  100.  
  101. #if HAVE_RESTARTABLE_SYSCALLS
  102.   if (fSjmp)
  103.     longjmp (sSjmp_buf, 1);
  104. #endif /* HAVE_RESTARTABLE_SYSCALLS */
  105. }
  106.  
  107. /* Prepare to catch a signal.  This is basically the ANSI C routine
  108.    signal, but it uses sigaction or sigvec instead if they are
  109.    available.  If fforce is FALSE, we do not set the signal if it is
  110.    currently being ignored.  If pfignored is not NULL and fforce is
  111.    FALSE, then *pfignored will be set to TRUE if the signal was
  112.    previously being ignored (if fforce is TRUE the value returned in
  113.    *pfignored is meaningless).  If we can't change the signal handler
  114.    we give a fatal error.  */
  115.  
  116. void
  117. usset_signal (isig, pfn, fforce, pfignored)
  118.      int isig;
  119.      RETSIGTYPE (*pfn) P((int));
  120.      boolean fforce;
  121.      boolean *pfignored;
  122. {
  123. #if HAVE_SIGACTION
  124.  
  125.   struct sigaction s;
  126.  
  127.   if (! fforce)
  128.     {
  129.       (void) (sigemptyset (&s.sa_mask));
  130.       if (sigaction (isig, (struct sigaction *) NULL, &s) != 0)
  131.     ulog (LOG_FATAL, "sigaction (%d): %s", isig, strerror (errno));
  132.  
  133.       if (s.sa_handler == SIG_IGN)
  134.     {
  135.       if (pfignored != NULL)
  136.         *pfignored = TRUE;
  137.       return;
  138.     }
  139.  
  140.       if (pfignored != NULL)
  141.     *pfignored = FALSE;
  142.     }
  143.  
  144.   s.sa_handler = pfn;
  145.   (void) (sigemptyset (&s.sa_mask));
  146.   s.sa_flags = SA_INTERRUPT;
  147.  
  148.   if (sigaction (isig, &s, (struct sigaction *) NULL) != 0)
  149.     ulog (LOG_FATAL, "sigaction (%d): %s", isig, strerror (errno));
  150.  
  151. #else /* ! HAVE_SIGACTION */
  152. #if HAVE_SIGVEC
  153.  
  154.   struct sigvec s;
  155.  
  156.   if (! fforce)
  157.     {
  158.       if (sigvec (isig, (struct sigvec *) NULL, &s) != 0)
  159.     ulog (LOG_FATAL, "sigvec (%d): %s", isig, strerror (errno));
  160.  
  161.       if (s.sv_handler == SIG_IGN)
  162.     {
  163.       if (pfignored != NULL)
  164.         *pfignored = TRUE;
  165.       return;
  166.     }
  167.  
  168.       if (pfignored != NULL)
  169.     *pfignored = FALSE;
  170.     }
  171.  
  172.   s.sv_handler = pfn;
  173.   s.sv_mask = 0;
  174.   s.sv_flags = SV_INTERRUPT;
  175.  
  176.   if (sigvec (isig, &s, (struct sigvec *) NULL) != 0)
  177.     ulog (LOG_FATAL, "sigvec (%d): %s", isig, strerror (errno));
  178.  
  179. #else /* ! HAVE_SIGVEC */
  180.  
  181.   if (! fforce)
  182.     {
  183.       if (signal (isig, SIG_IGN) == SIG_IGN)
  184.     {
  185.       if (pfignored != NULL)
  186.         *pfignored = TRUE;
  187.       return;
  188.     }
  189.  
  190.       if (pfignored != NULL)
  191.     *pfignored = FALSE;
  192.     }
  193.  
  194.   (void) signal (isig, pfn);
  195.  
  196. #endif /* ! HAVE_SIGVEC */
  197. #endif /* ! HAVE_SIGACTION */
  198. }
  199.  
  200. /* The routine called by the system independent code, which always
  201.    uses the same signal handler.  */
  202.  
  203. void
  204. usysdep_signal (isig)
  205.      int isig;
  206. {
  207.   usset_signal (isig, ussignal, FALSE, (boolean *) NULL);
  208. }
  209.